package com.example.up;

import android.util.Log;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import okhttp3.Request;

/**
 * Created by yinghao on 2017/2/28.
 * Email：yhaowa@outlook.com
 * <p>
 * 一个请求池对应一个文件，方便控制请求数, 控制临时文件数量
 */

class RequestPool {

    private static final String TAG = "RequestPool";
    private static int requestSize = 5;

    private BlockPool mBlockPool;
    private OKHttp.ProgressListener mProgressListener;
    private OKHttp.ResultCallback<String> mCallback;
    private OKHttp.RequestInfoListener mRequestListener;
    private Map<String, String> mParams;
    private String mFileKey;
    private String mUrl;


    private final long[] readBytesCounts = {0};
    private final RequestThread mRequestThread = new RequestThread();
    private List<String> mRequestList = new ArrayList<>();

    private String mSrcFileName;


    RequestPool(String url, final File srcFile, String fileKey,
                Map<String, String> params,
                final OKHttp.ResultCallback<String> callback,
                final OKHttp.ProgressListener progressListener,
                OKHttp.RequestInfoListener requestListener) {
        mProgressListener = progressListener;
        mRequestListener = requestListener;
        mParams = params;
        mFileKey = fileKey;
        mUrl = url;
        mBlockPool = new BlockPool(srcFile);
        mSrcFileName = srcFile.getName();
        mProgressListener = new OKHttp.ProgressListener() {
            @Override
            public void onProgress(long fileLengths, long readBytesCount, boolean blockReadDone,long blockStartTime) {
                readBytesCounts[0] += readBytesCount;
                if (blockReadDone) {
                    long time = System.currentTimeMillis()-blockStartTime;

                    Log.d(TAG, "onProgress: 分片上传完 length=" + fileLengths +" 耗时="+time+"ms");
                }
                progressListener.onProgress(srcFile.length(), readBytesCounts[0], blockReadDone,blockStartTime);
            }
        };
        mCallback = new OKHttp.ResultCallback<String>() {
            @Override
            public void onError(Request request, Exception e) {
                callback.onError(request, e);
            }

            @Override
            public void onResponse(String response) {
                notifyRequestThread(response);
                callback.onResponse(response);
            }
        };
    }

    /**
     * 自动补全requestSize  个  request去请求
     */
    private class RequestThread extends Thread {
        @Override
        public void run() {
            synchronized (mRequestThread) {
                while (true) {
//                    Log.d(TAG, "自动请求线程开始");
                    while (mRequestList.size() < requestSize) {
                        if (!addRequest()) {
//                            Log.d(TAG, "自动请求线程销毁");
                            return;
                        }
                    }
                    try {
//                        Log.d(TAG, "自动请求线程阻塞");
                        this.wait();
                    } catch (InterruptedException e) {
                        Log.e(TAG, "InterruptedException:" + e.getMessage());
                    }
                }
            }
        }
    }

    private void notifyRequestThread(String blockFileName) {
        synchronized (mRequestThread) {
            mRequestList.remove(blockFileName);
            mRequestThread.notify();
        }
    }

    private boolean addRequest() {
        Block block = mBlockPool.take();
        if (block == null) {
            return false;
        }
        mRequestList.add(block.file.getName());
        mParams.put("startPos", block.startPos + "");
        mParams.put("blockLength", block.length + "");
        mParams.put("fileTag", mSrcFileName);
        OKHttp.postAsyn(mUrl, mCallback, mProgressListener, block.file, mFileKey, mParams, mRequestListener);
        return true;
    }

    static void setRequestSize(int requestsize) {
        requestSize = requestsize;
    }

    void startUpload() {
        mRequestThread.start();
    }


}
